import axios from 'axios'

const API_BASE = '/api'

interface PingResult {
  ping: number
  jitter: number
}

class SpeedTestApi {
  async testPing(): Promise<PingResult> {
    const tests = []
    
    // 进行5次ping测试
    for (let i = 0; i < 5; i++) {
      const start = performance.now()
      
      try {
        await axios.get(`${API_BASE}/ping`, {
          timeout: 5000,
          headers: { 'Cache-Control': 'no-cache' }
        })
        
        const end = performance.now()
        tests.push(end - start)
      } catch (error) {
        console.error(`Ping test ${i + 1} failed:`, error)
        tests.push(1000) // 超时设为1000ms
      }
      
      // 测试间隔
      if (i < 4) {
        await new Promise(resolve => setTimeout(resolve, 200))
      }
    }
    
    const avgPing = tests.reduce((a, b) => a + b, 0) / tests.length
    const jitter = Math.sqrt(tests.reduce((sum, ping) => sum + Math.pow(ping - avgPing, 2), 0) / tests.length)
    
    return {
      ping: Math.max(avgPing, 1),
      jitter: Math.max(jitter, 0.1)
    }
  }

  async testDownloadSpeed(onProgress?: (speed: number) => void): Promise<number> {
    const testSizes = [1, 5, 10, 25] // MB
    let totalSpeed = 0
    
    for (let i = 0; i < testSizes.length; i++) {
      const size = testSizes[i]
      const start = performance.now()
      
      try {
        const response = await axios.get(`${API_BASE}/download/${size}`, {
          responseType: 'blob',
          timeout: 30000,
          headers: { 'Cache-Control': 'no-cache' },
          onDownloadProgress: (progressEvent) => {
            if (progressEvent.total) {
              const current = performance.now()
              const duration = (current - start) / 1000
              const downloadedMB = (progressEvent.loaded || 0) / (1024 * 1024)
              const currentSpeed = (downloadedMB * 8) / duration
              
              if (onProgress && duration > 0.1) {
                onProgress(Math.min(currentSpeed, 200))
              }
            }
          }
        })
        
        const end = performance.now()
        const duration = (end - start) / 1000
        const speed = (size * 8) / duration // Mbps
        
        totalSpeed += speed
        const currentAverage = totalSpeed / (i + 1)
        
        if (onProgress) {
          onProgress(Math.min(currentAverage, 200))
        }
        
        await new Promise(resolve => setTimeout(resolve, 100))
      } catch (error) {
        console.error(`Download test ${i + 1} failed:`, error)
        break
      }
    }
    
    return Math.min(totalSpeed / testSizes.length, 200)
  }

  async testUploadSpeed(onProgress?: (speed: number) => void): Promise<number> {
    const testSizes = [1, 2, 5] // MB
    let totalSpeed = 0
    
    for (let i = 0; i < testSizes.length; i++) {
      const size = testSizes[i]
      const data = new Blob([new ArrayBuffer(size * 1024 * 1024)])
      const formData = new FormData()
      formData.append('file', data, 'test-data.bin')
      
      const start = performance.now()
      
      try {
        await axios.post(`${API_BASE}/upload`, formData, {
          timeout: 30000,
          headers: {
            'Content-Type': 'multipart/form-data',
            'Cache-Control': 'no-cache'
          },
          onUploadProgress: (progressEvent) => {
            if (progressEvent.total) {
              const current = performance.now()
              const duration = (current - start) / 1000
              const uploadedMB = (progressEvent.loaded || 0) / (1024 * 1024)
              const currentSpeed = (uploadedMB * 8) / duration
              
              if (onProgress && duration > 0.1) {
                onProgress(Math.min(currentSpeed, 100))
              }
            }
          }
        })
        
        const end = performance.now()
        const duration = (end - start) / 1000
        const speed = (size * 8) / duration
        
        totalSpeed += speed
        const currentAverage = totalSpeed / (i + 1)
        
        if (onProgress) {
          onProgress(Math.min(currentAverage, 100))
        }
        
        await new Promise(resolve => setTimeout(resolve, 100))
      } catch (error) {
        console.error(`Upload test ${i + 1} failed:`, error)
        break
      }
    }
    
    return Math.min(totalSpeed / testSizes.length, 100)
  }
}

export const speedTestApi = new SpeedTestApi()